package com.gradle.quartz.batch.config;

import com.gradle.bean.employee.Employee;
import com.gradle.quartz.batch.listener.FileToDbJobListener;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.batch.MyBatisBatchItemWriter;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.PathResource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.scheduling.annotation.Async;

/**
 * @author ldanniel
 */
@Configuration
@Async
@EnableBatchProcessing
public class FileToDbConfig {
    @Autowired
    private FileToDbJobListener fileToDbJobListener;
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Value("${job.data.path}")
    private String filePath;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Bean
    public FlatFileItemReader<Employee> csvItemReader() {
        return new FlatFileItemReaderBuilder<Employee>()
                .name("employeeItemReader")
                .saveState(false)
                .resource(new PathResource(filePath))
                //指定解析器，使用#分割，默认是用,号
                .delimited().delimiter(",")
                //截取数据之后，数据怎么命名
                .names("id", "userName", "age", "address")
                //将解析的数据封装到User对象中-自动封装
                .targetType(Employee.class)
                .build();
    }

    @Bean
    public MyBatisBatchItemWriter<Employee> csvFileToDbBatchItemWriter() {
        MyBatisBatchItemWriter<Employee> writer = new MyBatisBatchItemWriter<>();
        //构建sqlSession类似Connection
        writer.setSqlSessionFactory(sqlSessionFactory);
        //指定需要执行sql语句对应mapper语句
        writer.setStatementId("com.gradle.mapper.EmployeeMapper.saveTemp");
        return writer;
    }

    @Bean
    public Step csvToDbStep() {
        return stepBuilderFactory.get("csvToDbStep")
                //一次读一万条
                .<Employee,Employee>chunk(10000)
                .reader(csvItemReader())
                .writer(csvFileToDbBatchItemWriter())
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .build();
    }

    @Bean
    public Job csvToDbJob()  {
        return jobBuilderFactory.get("csv-to-db-job")
                .start(csvToDbStep())
                .incrementer(new RunIdIncrementer())
                .listener(fileToDbJobListener)
                .build();
    }
}
